#include "N1File.h"
#include "N1Log.h"

N1NAME_DEF(N1File)

N1File::N1File() : m_file(NULL)
{
}

N1File::~N1File()
{
    close();
}

void N1File::close()
{
    if(m_file)
    {
#ifdef WINDOWS
        CloseHandle(m_file);
#else
        fclose(m_file);
#endif
        m_file = NULL;
    }
}

bool N1File::create(const N1PathChar* name)
{
    close();

#ifdef WINDOWS
    m_file = CreateFileW(name, FILE_ADD_FILE|GENERIC_READ|GENERIC_WRITE,
                         FILE_SHARE_READ, NULL,
                         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
#else
    m_file = fopen(name, "wb");
#endif
    return false;
}

bool N1File::openForRead(const N1PathChar* name)
{
    close();

#ifdef WINDOWS
    m_file = CreateFileW(name, GENERIC_READ, FILE_SHARE_READ, NULL,
                         OPEN_EXISTING, 0, NULL);
#else
    m_file = fopen(name, "rb");
#endif
    return false;
}

uint64 N1File::getSize() const 
{
#ifdef WINDOWS
    DWORD sizeHi;
    DWORD sizeLo;
    sizeLo = GetFileSize(m_file, &sizeHi);
    return (uint64)sizeHi<<32 + sizeLo;
#else
    return 0; //filelength( m_file );
#endif
}

uint64 N1File::getPosition() const 
{
#ifdef WINDOWS
    LONG  posHi = 0;
    DWORD posLo = SetFilePointer(m_file, 0, &posHi, FILE_BEGIN);
    return (uint64)posHi<<32 + posLo;
#else
    return 0;
#endif
}

uint64 N1File::setPosition(uint64 newPos)
{
#ifdef WINDOWS
    LONG  posHi = LONG(newPos >> 32);
    DWORD posLo = SetFilePointer(m_file, (LONG)newPos, &posHi, FILE_BEGIN);
    return (uint64)posHi<<32 + posLo;
#else
    return 0;
#endif
}

uint64 N1File::read(void* buffer, uint64 size)
{
#ifdef WINDOWS
    DWORD readed;
    if(!ReadFile(m_file, buffer, size, &readed, NULL))
    {
        N1Log(N1Log_Error, "N1File: ReadFile failed with %u", GetLastError());
    }
    return readed;
#else
    return 0;
#endif
}

uint64 N1File::write(const void* buffer, uint64 size)
{
#ifdef WINDOWS
    DWORD written;
    if(!WriteFile(m_file, buffer, size, &written, NULL))
    {
        N1Log(N1Log_Error, "N1File: ReadFile failed with %u", GetLastError());
    }
    return written;
#else
    return 0;
#endif
}
